package cn.bigfire.wedesk.action;

import cn.bigfire.wedesk.annotation.CMD;
import cn.bigfire.wedesk.bean.Wedesk;
import cn.bigfire.wedesk.net.protocol.Protocol;
import cn.bigfire.wedesk.service.bo.Context;
import cn.bigfire.wedesk.service.bo.CustInfo;
import cn.bigfire.wedesk.service.impl.LoginService;
import cn.bigfire.wedesk.store.AsyncUtil;
import cn.bigfire.wedesk.store.Stores;
import cn.bigfire.wedesk.store.Threads;
import cn.bigfire.wedesk.util.ByteUtil;
import com.alibaba.fastjson.JSON;
import io.netty.channel.Channel;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;


public class PcAction {

    @CMD(Wedesk.Cmd.CMD_PC_INFO)
    public void pcInfo(Wedesk.PCInfo pcInfo) {
        pcInfo.setCid(Threads.getChannelId());
        Stores.addPcInfo(Threads.getChannelId(), pcInfo);
    }

    @CMD(Wedesk.Cmd.CMD_REGISTER)
    public void register(Wedesk.RegisterReq registerReq) {
        if (registerReq == null) {
            Threads.getContext().send(Protocol.err("注册参数错误"));
            return;
        }
        if (Stores.hasUserName(registerReq.getUsername())) {
            Threads.getContext().send(Protocol.err("用户名已经存在"));
            return;
        }
        if (!registerReq.getPassword().equals(registerReq.getPassword2())) {
            Threads.getContext().send(Protocol.err("2次密码不一致"));
            return;
        }
        LoginService.register(registerReq);
    }

    @CMD(Wedesk.Cmd.CMD_LOGIN)
    public void login(Wedesk.LoginReq loginReq) {
        if (loginReq.getUsername() == null || loginReq.getPassword() == null) {
            Threads.getContext().send(Protocol.err("登录参数错误"));
        }
        LoginService.login(loginReq);
    }

    @CMD(Wedesk.Cmd.CMD_CTRL_MY_LIST)
    public Protocol ctrlList() {
        Context context = Threads.getContext();
        if (context != null) {
            System.out.println(context.getChannelId());
        }
        CustInfo custInfo = Threads.getCustInfo();
        if (custInfo == null) {
            return null;
        }
        Wedesk.CtrlMyListRes ctrlListRes = new Wedesk.CtrlMyListRes();
        ctrlListRes.setUsername(custInfo.getUserEntity().getUsername());
        ctrlListRes.setPcOnlineMap(Stores.findPcInfosByUsername(custInfo.getUserEntity().getUsername()));
        return Protocol.of(Wedesk.Cmd.CMD_CTRL_MY_LIST,ctrlListRes);
    }

    @CMD(Wedesk.Cmd.CMD_CTRL_OPEN)
    public void ctrlOpen(Wedesk.Ctrl ctrl) {
        //补渠道id
        ctrl.setFromCid(Threads.getChannelId());
        Stores.addCtrlOpen(ctrl);
        //数据转发
        Channel channel = Threads.getChannel(ctrl.getToCid());
        channel.writeAndFlush(Protocol.of(Wedesk.Cmd.CMD_CTRL_OPEN, ctrl));
    }

    @CMD(Wedesk.Cmd.CMD_CTRL_CLOSE)
    public void ctrlExecClose(Wedesk.Ctrl ctrl) {
        ctrl.setFromCid(Threads.getChannelId());
        Stores.removeCtrlOpen(ctrl);
        //数据转发
        Channel channel = Threads.getChannel(ctrl.getToCid());
        channel.writeAndFlush(Protocol.of(Wedesk.Cmd.CMD_CTRL_CLOSE, ctrl));
    }

    @CMD(Wedesk.Cmd.CMD_SCREENSHOT_DATA)
    public void imgData(Wedesk.ScreensHot screensHot) {
        ConcurrentHashMap<String, Wedesk.Ctrl> ctrlMap = Stores.findCtrlMap(Threads.getChannelId());
        AsyncUtil.submit(() -> {
            try {
                transferScreensHot(ctrlMap, screensHot);
            } catch (Exception e) {
                e.printStackTrace();
            }
        });
    }

    //转发截图数据给所有控制着
    public void transferScreensHot(Map<String, Wedesk.Ctrl> ctrlMap, Wedesk.ScreensHot screensHot) {
        ctrlMap.forEach((formId, ctrl) -> {
            Channel channel = Threads.getChannel(formId);
            if (channel != null) {
                channel.writeAndFlush(Protocol.of(Wedesk.Cmd.CMD_SCREENSHOT_DATA, screensHot));
            }
        });
    }

    @CMD(Wedesk.Cmd.CMD_CTRL_MOUSE)
    public void mouseEvent(Wedesk.MouseEvent mouseEvent) {
        try {
            mouseEvent.setFromCid(Threads.getChannelId());
            Channel channel = Threads.getChannel(mouseEvent.getToCid());
            channel.writeAndFlush(Protocol.of(Wedesk.Cmd.CMD_CTRL_MOUSE, mouseEvent));
        } catch (Exception e) {
            e.printStackTrace();
            System.err.println(JSON.toJSONString(Threads.onlineChannelIds()));
            System.err.println(mouseEvent.getToCid());
        }
    }

    @CMD(Wedesk.Cmd.CMD_CTRL_KEY_BOARD)
    public void keyboardEvent(Wedesk.KeyboardEvent keyboardEvent) {
        try {
            keyboardEvent.setFromCid(Threads.getChannelId());
            Channel channel = Threads.getChannel(keyboardEvent.getToCid());
            channel.writeAndFlush(Protocol.of(Wedesk.Cmd.CMD_CTRL_KEY_BOARD, keyboardEvent));
        } catch (Exception e) {
//            e.printStackTrace();
            System.err.println(JSON.toJSONString(Threads.onlineChannelIds()));
            System.err.println(keyboardEvent.getToCid());
        }

    }

}
